
/**
\file
Defines the rainbow::stencil_state class.
\author Sean Tromans
*/

#ifndef	RAINBOW_GRAPHICS_DEVICE_STENCIL_STATE_HPP
#define	RAINBOW_GRAPHICS_DEVICE_STENCIL_STATE_HPP

#include <sun/gl.hpp>
#include <sun/lua/lua_fwd.hpp>

namespace rainbow
{

	/**
	Defines the settings for a user defined GPU stencil state.
	\author Sean Tromans
	*/
	struct stencil_state
	{
		/**
		Default Constructor.
		\author Sean Tromans
		*/
		stencil_state( );

		/**
		Applies any changes from the provided stencil_state to OpenGL.
		@param other The currently active stencil_state.
		\author Sean Tromans
		*/
		void apply( stencil_state const & other ) const;

		bool	enabled;	///< Whether the stencil test is enabled.

		GLenum	front_func;			///< The stencil function to be applied to all front facing polygons.
		GLint	front_ref;			///< The stencil reference value to be used with front_func.
		GLuint	front_func_mask;	///< The mask to be applied to both the current stencil value and the reference value when applying front_func.

		GLenum	back_func;		///< The stencil function to be applied to all back facing polygons.
		GLint	back_ref;		///< The stencil reference value to be used with back_func.
		GLuint	back_func_mask;	///< The mask to be applied to both the current stencil value and the reference value when applying back_func.

		GLenum	front_stencil_fail;	///< What action should be taken if the stencil test fails on front facing polygons.
		GLenum	front_depth_fail;	///< What action should be taken if the depth test fails on front facing polygons.
		GLenum	front_both_pass;	///< What action should be taken if both the depth and stencil test pass on front facing polygons.

		GLenum	back_stencil_fail;	///< What action should be taken if the stencil test fails on back facing polygons.
		GLenum	back_depth_fail;	///< What action should be taken if the depth test fails on back facing polygons.
		GLenum	back_both_pass;		///< What action should be taken if both the depth and stencil test pass on back facing polygons.

		GLuint	front_mask;	///< The bits of the stencil buffer which can be written by front facing polygons.
		GLuint	back_mask;	///< The bits of the stencil buffer which can be written by back facing polygons.

		/**
		Exposes the stencil_state to lua.
		@param L The Lua State being initialised.
		\author Sean Tromans.
		*/
		static void lua_interface( lua_State * L );
	};

	/**
	Comparrison operator for stencil_states.
	@param lhs The first stencil_state being compared.
	@param rhs The second stencil_state being compared.
	@return True if the stencil_states are equal.
	\author Sean Tromans
	*/
	bool operator == ( stencil_state const & lhs, stencil_state const & rhs );

}

#endif	//RAINBOW_GRAPHICS_DEVICE_STENCIL_STATE_HPP
